/**
 * Simple window class
 * 
 * @see WindowManager
 */
package com.kusiri.window 
{
	import com.kusiri.kframework.ui.IKfUiComponent;
	
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	
	import mx.containers.HBox;
	import mx.controls.Button;
	import mx.core.Application;
	import mx.core.Container;
	import mx.effects.Resize;
	import mx.events.EffectEvent;
	import mx.events.ResizeEvent;
	import mx.managers.CursorManager;
	
	public class Window extends WindowBase 
	{
		
		private var mouseDownTimeoutId:uint;
		public var windowManager:WindowManager;
		
		public var kfUiComponent : IKfUiComponent;
		
		public var showClose:Boolean = false;
		public var showMaximize:Boolean = false;
		public var enableResize:Boolean = false;
				
		[Embed(source="/assets/img/resizeCursor.png")]
		private static var resizeCursor:Class;

		private var oldWidth:Number;
		private var oldHeight:Number;
		private var oldX:Number;
		private var oldY:Number;
		private var open:Boolean = true;
		private var normalMaxButton:Button	= new Button();
		private var closeButton:Button		= new Button();
		private var resizeHandler:Button	= new Button();
		private var upMotion:Resize			= new Resize();
		private var downMotion:Resize		= new Resize();
		private var oPoint:Point 			= new Point();
		private var resizeCur:Number		= 0;	
		private var onResizeSavePosDisabled:Boolean = false;	
		private var titleIconsHbox:HBox;

		private const MIN_WIDTH : int = 100;
		private const MIN_HEIGHT : int = 40;
		
		// move to a style
		private const TITLE_ICONS_PADDING_TOP : int = 8;
		private const TITLE_ICONS_PADDING_RIGHT : int = 10;

		public function Window()
		{
			super();
		}

		protected function get application() : Application
		{
			return Application.application as Application;
		}

		protected function get windowCanvas() : Container
		{
			return windowManager.windowCanvas;
		}

		override protected function createChildren():void 
		{
			minHeight = MIN_HEIGHT;
			minWidth = MIN_WIDTH;
			styleName = '';
				
			super.createChildren();
			
			
			
			doubleClickEnabled = true;
			
			setupTitleBar();
			setupResize();
				
			addEventListeners();
		}
		
		override public function invalidateDisplayList():void
		{
			super.invalidateDisplayList();
		}

		override protected function updateDisplayList (unscaledWidth:Number, unscaledHeight:Number):void
		{
			super.updateDisplayList(unscaledWidth, unscaledHeight);
			
			// Do this or the icons won't appear!
			titleIconsHbox.setActualSize( titleIconsHbox.getExplicitOrMeasuredWidth(),titleIconsHbox.getExplicitOrMeasuredHeight() );
			
			positionTitleIcons();
			
		}
		
		protected function positionTitleIcons() : void
		{
			// Position the HBox
			var y:int = TITLE_ICONS_PADDING_TOP;
			var x:int = width - titleIconsHbox.width - TITLE_ICONS_PADDING_RIGHT;
			titleIconsHbox.move(x, y);
		}
		
		protected function setupResize() : void
		{
			if (enableResize) 
			{
				resizeHandler.width     = 12;
				resizeHandler.height    = 12;
				resizeHandler.styleName = "resizeHndlr";
				rawChildren.addChild(resizeHandler);
			}
		}
		
		protected function setupTitleBar() : void
		{	
			
			titleBar.height = 50;
			
			titleIconsHbox = new HBox();
			titleIconsHbox.x = 0;
			titleIconsHbox.y = 0;
			titleIconsHbox.percentWidth = 100;
			titleIconsHbox.percentHeight = 100;
			
			if (showMaximize) 
			{
				normalMaxButton.width     	= 10;
				normalMaxButton.height    	= 10;
				normalMaxButton.buttonMode    = true;
				normalMaxButton.useHandCursor = true;
				normalMaxButton.styleName 	= "increaseBtn";
				titleIconsHbox.addChild(normalMaxButton);	
			}
			
			if (showClose)
			{
				closeButton.width     		= 10;
				closeButton.height    		= 10;
				closeButton.styleName 		= "closeBtn";
				closeButton.buttonMode	   = true;
				closeButton.useHandCursor = true;
				titleIconsHbox.addChild(closeButton);
			}	
			
			titleBar.addChild(titleIconsHbox);
		}
			
		protected function savePos() : void
		{
			oldWidth = width;
			oldHeight = height;
			oldX = x;
			oldY = y;
		}
			
		protected function onResize( event : Event):void 
		{
			
			if ( ! onResizeSavePosDisabled ) 
			{
				savePos();
			}

			if (enableResize) 
			{
				this.resizeHandler.y = this.unscaledHeight - resizeHandler.height - 1;
				this.resizeHandler.x = this.unscaledWidth - resizeHandler.width - 1;
			}
			
			titleIconsHbox.x = titleBar.width - titleIconsHbox.width - TITLE_ICONS_PADDING_RIGHT;
		}
		
		protected function addEventListeners():void 
		{

			
			addEventListener(ResizeEvent.RESIZE, onResize);
			addEventListener(MouseEvent.CLICK, onClick, true, 500);
			
			titleBar.addEventListener(MouseEvent.MOUSE_DOWN, onTitleBarMouseDown);
			titleBar.addEventListener(MouseEvent.DOUBLE_CLICK, onTitleBarDoubleClick);
			
			if (showMaximize) 
			{
				normalMaxButton.addEventListener(MouseEvent.CLICK, onMaximizeClick);
			}
			
			if (showClose)
			{
				closeButton.addEventListener(MouseEvent.CLICK, onCloseClick);
			}
			
			if (enableResize) 
			{
				resizeHandler.addEventListener(MouseEvent.MOUSE_OVER, onResizeMouseOver);
				resizeHandler.addEventListener(MouseEvent.MOUSE_OUT, onResizeMouseOut);
				resizeHandler.addEventListener(MouseEvent.MOUSE_DOWN, onResizeMouseDown);
			}
		}
		
		protected function onClick(event:MouseEvent):void 
		{
			focus();
		}
		
		/**
		 * Bring the window into focus
		 */
		public function focus() : void
		{
			windowManager.focus(this);
		}
		
		
		protected function onTitleBarMouseDown(event:MouseEvent):void 
		{
			onStopDrag();
			
			application.addEventListener(MouseEvent.MOUSE_UP, onStopDrag, false, 500, true);
			application.addEventListener(MouseEvent.MOUSE_MOVE, onStartDrag, false, 250, true );
			
			focus();
			
		}

		protected function onStartDrag(event:Event=null) : void
		{
			// no need for this handler any more 
			application.removeEventListener(MouseEvent.MOUSE_MOVE, onStartDrag, false);
			application.addEventListener(MouseEvent.MOUSE_UP, onStopDrag, false, 500, true);
			startDrag(false, new Rectangle(0, 0, Math.max(screen.width, windowCanvas.width) - width, Math.max(screen.height, windowCanvas.height) - height));
			alpha = 0.5; 
		}

		protected function onStopDrag(event:Event=null) : void
		{
			stopDrag();
			application.removeEventListener(MouseEvent.MOUSE_MOVE, onStartDrag, false);
			application.removeEventListener(MouseEvent.MOUSE_UP, onStopDrag, false);
			if (alpha != 1) alpha = 1;
		}

		protected function onTitleBarDoubleClick(event:MouseEvent):void 
		{
			onStopDrag();
			
			if (open) 
			{
				onResizeSavePosDisabled = true;
				upMotion.target = this;
				upMotion.duration = 300;
				upMotion.heightFrom = oldHeight;
				upMotion.heightTo = 28;
				upMotion.end();
				upMotion.play();
				resizeHandler.visible = false;
			} 
			else 
			{
				onResizeSavePosDisabled = false;
				downMotion.target = this;
				downMotion.duration = 300;
				downMotion.heightFrom = 28;
				downMotion.heightTo = oldHeight;
				downMotion.end();
				downMotion.play();
				downMotion.addEventListener(EffectEvent.EFFECT_END, onEndEffect);
			}

			open = ! open;
		}
						
		protected function onEndEffect(event:EffectEvent):void 
		{
			resizeHandler.visible = true;
		}

		protected function onMaximizeClick(event:MouseEvent):void 
		{
			
			
			if (normalMaxButton.styleName == "increaseBtn") 
			{
				if (height > 28) 
				{
					resizeHandler.visible = false;
					onResizeSavePosDisabled = true;
					
					x = 0;
					y = 0;
					width = screen.width;
					height = screen.height;
					normalMaxButton.styleName = "decreaseBtn";
				}
			} 
			else 
			{
				
				x = oldX;
				y = oldY;
				width = oldWidth;
				height = oldHeight;
				normalMaxButton.styleName = "increaseBtn";
				
				onResizeSavePosDisabled = false;
				resizeHandler.visible = true;
			}
		}
		
		protected function onCloseClick(event:MouseEvent):void 
		{
			removeEventListener(MouseEvent.CLICK, onClick);
			remove();
		}
		
		public function remove() : void
		{
			windowManager.removeWindow(this);
		}
		
		
		protected function onResizeMouseOver(event:MouseEvent):void 
		{
			resizeCur = CursorManager.setCursor(resizeCursor);
		}
		
		protected function onResizeMouseOut(event:MouseEvent):void 
		{
			CursorManager.removeCursor(resizeCur);
		}
		
		protected function onResizeMouseDown(event:MouseEvent):void 
		{
			savePos();
			onResizeSavePosDisabled = true;
			
			//resizeCur = CursorManager.setCursor(resizeCursor);
			oPoint.x = mouseX;
			oPoint.y = mouseY;
			oPoint = localToGlobal(oPoint);
			
			application.addEventListener(MouseEvent.MOUSE_MOVE, onResizeMouseMove, false, 0, true);
			application.addEventListener(MouseEvent.MOUSE_UP, onResizeMouseUp, false, 0, true);		
		}
		
		protected function onResizeMouseMove(event:MouseEvent):void 
		{
			var oPointNew : Point = new Point();	
			oPointNew.x = mouseX;
			oPointNew.y = mouseY;
			oPointNew = localToGlobal(oPointNew);
			
			var xPlus:Number = oPointNew.x - oPoint.x;			
			var yPlus:Number = oPointNew.y - oPoint.y;
			
			if (oldWidth + xPlus > MIN_WIDTH) 
			{
				width = oldWidth + xPlus;
			}
			
			if (oldHeight + yPlus > MIN_HEIGHT) 
			{
				height = oldHeight + yPlus;
			}
			
		}
		
		protected function onResizeMouseUp(event:MouseEvent):void 
		{
			onResizeSavePosDisabled = false;
			
			application.removeEventListener(MouseEvent.MOUSE_MOVE, onResizeMouseMove);
			application.removeEventListener(MouseEvent.MOUSE_UP, onResizeMouseUp);
			
			//CursorManager.removeCursor(resizeCur);
		}
	}
	
}